package com.shujia.scala

object Demo11Fun2 {
  def main(args: Array[String]): Unit = {

    /**
      * 面向对象编程：将对象传来传去，对象是有类型的，方法的参数是有类型限制的
      *
      * 面向函数编程：将函数传来传去，函数也是有类型的，接受函数的方法同样有类型限制
      *
      *
      * 高阶函数
      * 1、以函数作为参数
      * 2、以函数作为返回值
      *
      *
      */

    /**
      * 函数的类型是有函数参数的类型和返回值的类型决定
      *
      * def fun1(str: String): Int = {
      *       str.toInt
      * }
      *
      * 这是一个参数为String 返回值为Int类型的函数
      *
      *
      *
      */


    /**
      * 以函数作为参数- --  定义一个方法方法的参数是一个函数
      *
      * fun1 的参数是一个函数，是一个参数为String 返回值为Int类型的函数
      *
      * String => Int  ----> 描述函数的类型
      *
      */


    def fun1(f: String => Int): Unit = {

      // f 相当于fun2的引用
      //调用传进来的函数
      val i: Int = f("100")
      println(i)
    }

    //这是一个参数为String 返回值为Int类型的函数
    def fun2(str: String): Int = {
      str.toInt + 1
    }

    def fun3(str: String) = str.toInt + 2

    //调用fun1,传入fun2
    fun1(fun2)
    fun1(fun3)

    //使用mabda表达式调用函数
    fun1((s: String) => s.toInt + 100)
    //lambda表达式的参数类型可以自动推断出来
    fun1(s => s.toInt + 1000)
    //如果lambda表达式的参数只使用了一次可以通过下划线代替
    fun1(_.toInt + 10000)


    /**
      * lambda表达式--- 对函数定义的简写--匿名函数
      *
      * (s: String) => s.toInt
      *
      * =>  前面是函数的参数名和参数额类型，
      * =>  后面是函数体和返回值
      */

    def fun4(str: String): Int = {
      str.toInt + 1
    }


    val lam: String => Int = (str: String) => str.toInt + 1


    println(lam("200"))


  }

}
